package com.sharer.last.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sharer.last.base.enums.BooleanEnum;
import com.sharer.last.base.enums.BusinessExceptionCode;
import com.sharer.last.base.enums.ExceptionPrefixParamEnum;
import com.sharer.last.base.exception.BusinessException;
import com.sharer.last.base.model.PageVO;
import com.sharer.last.base.support.QueryCondition;
import com.sharer.last.base.utils.ConvertUtil;
import com.sharer.last.base.utils.StringUtil;
import com.sharer.last.model.dto.moment.MomentChangeDTO;
import com.sharer.last.model.dto.moment.MomentQueryDTO;
import com.sharer.last.model.po.*;
import com.sharer.last.model.vo.moment.MomentVO;
import com.sharer.last.service.RedisService;
import com.sharer.last.utils.BeanUtil;
import com.sharer.last.wrapper.MomentWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sharer.last.mapper.MomentMapper;
import com.sharer.last.service.MomentService;


import javax.annotation.Resource;

/**
 * 博客动态业务层实现
 *
 * @ClassName MomentServiceImpl
 * @Author wangjin
 * @Date 2023/5/5 20:45
 * @Description
 * @Version 1.0
 */
@Service
public class MomentServiceImpl extends ServiceImpl<MomentMapper, MomentPO> implements MomentService {
    @Resource
    MomentMapper momentMapper;

    @Resource
    MomentWrapper momentWrapper;

    @Resource
    RedisService redisService;

    /**
     * 根据id查询动态
     *
     * @param id 动态id
     * @return
     */
    @Override
    public MomentVO findById(Long id) {
        MomentPO momentPO = this.getById(id);
        if (momentPO == null) {
            return null;
        }
        return momentWrapper.entityVO(momentPO);
    }

    /**
     * 分页查询
     *
     * @param queryDTO
     * @return
     */
    @Override
    public PageVO<MomentVO> selectListByPage(MomentQueryDTO queryDTO) {
        LambdaQueryWrapper<MomentPO> qw   = this.buildQueryWrapper(queryDTO);
        IPage<MomentPO>              page = this.page(QueryCondition.getPage(queryDTO.getPage()), qw);
        return momentWrapper.toPageVO(page);
    }

    /**
     * 发布动态
     *
     * @param dto
     */
    @Override
    public void createMoment(MomentChangeDTO dto) {
        MomentPO momentPO = BeanUtil.copy(dto, MomentPO.class);
        momentPO.setId(null);
        if (!this.save(momentPO)) {
            throw new BusinessException(BusinessExceptionCode.DATA_INSERT_FAIL, ExceptionPrefixParamEnum.MOMENT);
        }
    }

    /**
     * 更新动态
     *
     * @param dto
     */
    @Override
    public void updateMoment(MomentChangeDTO dto) {
        Long id = dto.getId();
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.MOMENT);
        }
        // 查询数据是否存在
        MomentPO moment = this.getById(id);
        if (moment == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.MOMENT);
        }
        // 更新操作
        MomentPO momentPO = BeanUtil.copy(dto, MomentPO.class);
        momentPO.setId(null);
        LambdaQueryWrapper<MomentPO> qw = new LambdaQueryWrapper<>();
        qw.eq(MomentPO::getId, id);
        if (!this.update(momentPO, qw)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.MOMENT);
        }
    }

    /**
     * 删除动态
     *
     * @param id
     */
    @Override
    public void removeMomentById(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.MOMENT);
        }
        // 查询数据是否存在
        MomentPO moment = this.getById(id);
        if (moment == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.MOMENT);
        }
        if (!this.removeById(id)) {
            throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.MOMENT);
        }
    }

    /**
     * 更新动态是否可见
     *
     * @param id
     * @param published 是否可见
     */
    @Override
    public void updatePublished(Long id, Integer published) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.MOMENT);
        }

        // 查询数据是否存在
        MomentPO moment = this.getById(id);
        if (moment == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.MOMENT);
        }
        LambdaQueryWrapper<MomentPO> qw = new LambdaQueryWrapper<>();
        qw.eq(MomentPO::getId, id);
        MomentPO momentPO = MomentPO.builder()
                .isPublished(published)
                .build();
        if (!this.update(momentPO, qw)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.MOMENT);
        }
    }

    /**
     * 动态点赞
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addLikeByMomentId(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.MOMENT);
        }

        // 查询数据是否存在
        MomentPO moment = this.getById(id);
        if (moment == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.MOMENT);
        }
        LambdaQueryWrapper<MomentPO> qw = new LambdaQueryWrapper<>();
        qw.eq(MomentPO::getId, id);
        MomentPO momentPO = MomentPO.builder()
                .likes(moment.getLikes() + 1)
                .build();
        if (!this.update(momentPO, qw)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.MOMENT);
        }
    }

    private LambdaQueryWrapper<MomentPO> buildQueryWrapper(MomentQueryDTO queryDTO) {
        LambdaQueryWrapper<MomentPO> qw     = new LambdaQueryWrapper<>();
        // 数据权限范围
        String  adminToken = queryDTO.getAdminToken();
        String access_token = (String) redisService.get("access_token");
        if (StringUtil.isBlank(adminToken) || !adminToken.equals(access_token)) {
            qw.in(MomentPO::getIsPublished, BooleanEnum.TRUE.getCode());
        }
        return qw;
    }
}
